package com.herui.iot.ui.view.ecg;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.herui.sdyu_lib.utils.LogUtils;
import com.herui.sport_care.ui.view.ecg.bean.EcgShowType;
import com.herui.sport_care.ui.view.ecg.bean.EcgStyle;
import com.herui.sport_care.ui.view.ecg.bean.Point;
import com.herui.sport_care.ui.view.ecg.bean.WavePos;

import java.util.ArrayList;
import java.util.List;

import static com.herui.sport_care.ui.view.ecg.bean.EcgShowType._4x3;
import static com.herui.sport_care.ui.view.ecg.bean.EcgShowType.getWavePos;


/**
 * Created by amanda.shan on 2017/2/23.
 */

public abstract class AnimEcgView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    public String syn = "syn";

    protected List<LeadView> leadViews = new ArrayList<>();

    protected EcgShowType ecgShowType;

    // 显示单个wave
    protected boolean oneLeadType;    // 单导显示模式
    protected WaveView showWaveView;
    protected LeadView singalWaveView;

    // 点击监听
    private float downX, downY;
    private float lastX, lastY;
    private long downTime;

    protected Thread refreshShowThread;
    protected boolean isRunning;
    protected boolean singleMode;
    protected int singleModeLeadIndex;

    protected SurfaceHolder surfaceHolder;

    protected boolean touchProcess = true;

    public abstract void fling(float flingX, float flingY);


    public AnimEcgView(Context context) {
        super(context);
        init();
    }

    public AnimEcgView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AnimEcgView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    protected void init() {
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
        setEcgShowType(_4x3);
    }

    public void setSingleMode(boolean singleMode, int singleModeLeadIndex) {

        oneLeadType = singleMode;
        this.singleMode = singleMode;

        if (singleMode) {
            LeadView leadView = leadViews.get(singleModeLeadIndex);
            WavePos wavePos = new WavePos();
            wavePos.setlTop(new Point(0, 0));
            wavePos.setlBot(new Point(0, getHeight()));
            wavePos.setrTop(new Point(getWidth(), 0));
            wavePos.setrBot(new Point(getWidth(), getHeight()));
            singalWaveView = new LeadView(wavePos, leadView.getFlag(), leadView.getLeadNo(),
                    leadView.getDescribe());
        } else {
            singalWaveView = null;
        }

    }

    public void setEcgShowType(EcgShowType ecgShowType) {

        LogUtils.d("ento setEcgShowType");
        synchronized (syn) {
//            if (!ecgShowType.equals(this.ecgShowType)) {
            this.ecgShowType = ecgShowType;

            leadViews.clear();
            for (int i = 0; i < 12; ++i) {
                leadViews.add(new LeadView(getWavePos
                        (ecgShowType, i, getWidth(),
                                getHeight()), i, i, EcgStyle.ECGTEXT[i]));
            }

            if (ecgShowType.equals(_4x3))
                leadViews.add(new LeadView(getWavePos
                        (ecgShowType, -1, getWidth(),
                                getHeight()), -1, 1, EcgStyle.ECGTEXT[1]));

            LogUtils.d("setEcgShowType");

            animShow();
//            }

            if (singleMode && singalWaveView != null) {
                WavePos wavePos = new WavePos();
                wavePos.setlTop(new Point(0, 0));
                wavePos.setlBot(new Point(0, getHeight()));
                wavePos.setrTop(new Point(getWidth(), 0));
                wavePos.setrBot(new Point(getWidth(), getHeight()));
                singalWaveView.setWavePos(wavePos);
            }
        }
    }

    public void startRefreshScreem() {
        if (!isRunning) {
            isRunning = true;
            refreshShowThread = new Thread(this);
            refreshShowThread.start();
        }
    }

    public void stopRefreshScreem() {
        isRunning = false;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
//        isRunning = true;
//        refreshShowThread = new Thread(this);
//        refreshShowThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isRunning = false;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        LogUtils.d("onSizeChangedxxx:" + w + "   " + h);

        EcgShowType tempEcgShowType = ecgShowType;
        if (tempEcgShowType == null)
            tempEcgShowType = _4x3;
        ecgShowType = null;
        setEcgShowType(tempEcgShowType);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (!touchProcess)
            return false;

        if (singleMode)
            return false;

        for (WaveView leadView : leadViews) {
            if (leadView.isAniming())
                return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                lastX = downX;
                lastY = downY;
                downTime = System.currentTimeMillis();
//                LogUtils.d(String.format("ACTION_DOWN:(%f,%f)", event.getX(), event.getY()));
                break;
            case MotionEvent.ACTION_UP:
//                LogUtils.d(String.format("ACTION_UP:(%f,%f)", event.getX(), event.getY()));
                if ((System.currentTimeMillis() - downTime) < 500 && Math.sqrt((event.getX() -
                        downX) * (event.getX() - downX) + (event.getY() -
                        downY) * (event.getY() - downY)) < 10) {
                    switch (ecgShowType) {
                        case _1x12:
                        case _2x6:
                            if (showWaveView == null) {
                                for (LeadView leadView : leadViews) {
                                    if (leadView.isTuchThis(event.getX(), event.getY())) {
                                        showWaveView = leadView;
                                        oneLeadType = true;
                                        animOneShow(leadView);
                                        clearDate();
                                        return true;
                                    }
                                }
                            } else if (showWaveView.isTuchThis(event.getX(), event.getY())) {
                                oneLeadType = false;
                                animOneHide(showWaveView);
                                clearDate();
                                return true;
                            }
                            break;
                        case _4x3:
                            synchronized (syn) {
                                int chose = -1;
                                for (int i = 0; i < 12; ++i) {
                                    if (leadViews.get(i).isTuchThis(event.getX(), event.getY())) {
                                        chose = i;
                                        break;
                                    }
                                }
                                if (chose != -1) {
                                    leadViews.remove(12);
                                    LeadView leadView = new LeadView(getWavePos
                                            (ecgShowType, -1, getWidth(), getHeight()), -1, chose,
                                            EcgStyle.ECGTEXT[chose]);
                                    leadViews.add(leadView);
                                    clearDate();
                                    animShow(leadView);
                                }
                            }
                            break;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
//                LogUtils.d(String.format("ACTION_MOVE:(%f,%f)", event.getX(), event.getY()));
                float flingX = flingX(event);
                float flingY = flingY(event);
                if (flingX != 0 || flingY != 0) {
                    fling(flingX, flingY);
                }
                break;
        }
        return true;
    }

    private float flingX(MotionEvent event) {
        float f = event.getX(0) - lastX;
        if (Math.abs(f) > 1) {
            lastX = event.getX(0);
            return f;
        } else
            return 0;
    }

    private float flingY(MotionEvent event) {
        float f = event.getY(0) - lastY;
        if (Math.abs(f) > 1) {
            lastY = event.getY(0);
            return f;
        } else
            return 0;
    }


    protected void clearDate() {
        for (LeadView leadView : leadViews) {
            leadView.earsePoints();
        }
    }

    protected void animShow() {

        for (LeadView leadView : leadViews) {
            animShow(leadView);
        }
    }

    protected void animShow(LeadView leadView) {
        Point lTop = leadView.getlTop();
        Point lBot = leadView.getlBot();
        Point rTop = leadView.getrTop();
        Point rBot = leadView.getrBot();

        Point startLTop = lTop;
        Point endLTop = lTop;
        Point startLBot = lBot;
        Point endLBot = lBot;
        Point startRTop = new Point(lTop.x, rTop.y);
        Point endRTop = rTop;
        Point startRBot = new Point(lTop.x, rBot.y);
        Point endRBot = rBot;

        leadView.startAnim(startLTop, endLTop, startLBot, endLBot, startRTop, endRTop,
                startRBot, endRBot);
    }

    protected void animOneHide(WaveView leadView) {

        Point lTop = leadView.getlTop();
        Point lBot = leadView.getlBot();
        Point rTop = leadView.getrTop();
        Point rBot = leadView.getrBot();

        WavePos wavePos = getWavePos(ecgShowType, leadView.getFlag(), getWidth(),
                getHeight());

        Point startLTop = lTop;
        Point endLTop = wavePos.getlTop();
        Point startLBot = lBot;
        Point endLBot = wavePos.getlBot();
        Point startRTop = rTop;
        Point endRTop = wavePos.getrTop();
        Point startRBot = rBot;
        Point endRBot = wavePos.getrBot();

        leadView.startAnim(startLTop, endLTop, startLBot, endLBot, startRTop, endRTop,
                startRBot, endRBot);
    }

    protected void animOneShow(WaveView leadView) {

        Point lTop = leadView.getlTop();
        Point lBot = leadView.getlBot();
        Point rTop = leadView.getrTop();
        Point rBot = leadView.getrBot();

        Point startLTop = lTop;
        Point endLTop = new Point(0, 0);
        Point startLBot = lBot;
        Point endLBot = new Point(0, getHeight());
        Point startRTop = rTop;
        Point endRTop = new Point(getWidth(), 0);
        Point startRBot = rBot;
        Point endRBot = new Point(getWidth(), getHeight());

        leadView.startAnim(startLTop, endLTop, startLBot, endLBot, startRTop, endRTop,
                startRBot, endRBot);
    }
}
